package paleGoldenRod.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import paleGoldenRod.client.MessagingService;
import paleGoldenRod.client.WTGameStatus;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
/**
 * Returns suggestions from a dictionary and from what the user inputs.
 */
public class MessagingServiceImpl extends RemoteServiceServlet implements MessagingService {
	/**
	 * 
	 */
	private static final long serialVersionUID = -190827977040318307L;
	static String data;
	int playersTurn=0;
	int numUsers=0;
	ArrayList lastMove;
	public MessagingServiceImpl(){
	}
	public void sendString(String message){
		data=message;
	}
	public String getString(){
		return data;
	}	
	public Integer endTurn(ArrayList addedLetters, String[] words, int player) {
		return processTurn(addedLetters, words);
	}
	private Integer processTurn(ArrayList addedLetters, String[] word) {
		System.out.println("Message recieved: "+addedLetters);
		lastMove=addedLetters;
		playersTurn = ++playersTurn%2;
		System.out.println("Recieved the following words: "+word[0]+" "+word[1]);
		int score = scoreWord(word[0]);
		score+=scoreWord(word[1]);
		return new Integer(score);
	}
	private int scoreWord(String word) {
		if(word.length()<2)
			return 0;
/*		boolean isReal;
		GoogleSearch s = new GoogleSearch();
		s.setKey("e7Jtg/lQFHIdNfA+Dko82WnB4W7yz5E3");
		//System.out.println("Searching for "+word);
		s.setQueryString(word);
		GoogleSearchResult result = null;
		try{
		//System.out.println(s.doSpellingSuggestion(word));
		isReal=(s.doSpellingSuggestion(word)==null);
		result = s.doSearch();
		}catch(GoogleSearchFault f){
			return(0);
		}*/
		System.out.println("Checking score of word "+word+"...");
		int ghits = getURL(word);

		int value = (int)(Math.log10(ghits)*10.0);//use logarithmic scale to display range on slider
		return value;
	}
	public int getURL(String text) {
	    String URL = "";
	    try {
	        Socket s = new Socket("www.google.com",80);
	        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
	        bw.write("GET /search?hl=en&q=" + URLEncoder.encode(text) + " HTTP/1.0\r\n");
	        bw.write("User-Agent: Mozilla/1.0 (compatible; NCSA Mosaic; Atari 800-ST)\r\n");
	        bw.write("Connection: close\r\n\r\n");
	        bw.flush();
	        
	        InputStreamReader in = new InputStreamReader(s.getInputStream());
	        BufferedReader buffer = new BufferedReader(in);
	        String line;
	        
//	        Pattern imgPattern = Pattern.compile("imgurl=([^&]+)&imgrefurl");
//	        Pattern imgPattern = Pattern.compile("/(</b> of about <b>)[0-9,+](</b> for <b>)/");
//	        while ((line = buffer.readLine()) != null) {
//	            Matcher match = imgPattern.matcher(line);
//	            if (match.find()) {
//	            	System.out.println("Pattern Found:" + match.group(1));
//	                URL = match.group(1);
//	                break;
//	            }
//	        }
	        int i;
	        System.out.println("got here");
	        while((line = buffer.readLine()) !=null){
	        	//System.out.println(line);
	        	if((i = line.indexOf("</b> of about <b>"))>=0){
	        		String results = line.substring(i+17);
	        		int end = results.indexOf("</b>");
	        		results = results.substring(0, end).replace(",", "");
	        		System.out.println("Pattern Found:" + results);
	        		URL= results;
	        		break;
	        	}
	        }
	        in.close();
	    } catch (Exception e) {}
	    return Integer.parseInt(URL);
	}
	public ArrayList update(int player) {
		if(player==playersTurn){
			ArrayList tmp = lastMove;
			lastMove=null;
			return tmp;
		}
		return null;
	}
	public Integer getPlayerID() {
		return numUsers++;
	}
	
	/*
	 * =========== Below functions are for Word train ==============
	 * they all start with wt
	 */
	
	private class WTGame {
		public Integer cpeople = new Integer(0);
		public Integer cresult = new Integer(-1);
		public ArrayList<String> rgpeople = new ArrayList<String>();
		public StringBuilder sentence = new StringBuilder();
		public StringBuilder spacesentence = new StringBuilder();
		public Integer currentPlayer = new Integer(-1);
	}
	
	static final Map<Integer, WTGame> m_wtid2game = new HashMap<Integer, WTGame>(); 
	/**
	 * 
	 */
	public Integer wtJoinGame(Integer gameid, Integer cpeople, String username)
	{
		WTGame curgame = m_wtid2game.get(gameid);
		if (curgame == null) {
			curgame = new WTGame();
			curgame.cpeople = cpeople;
			m_wtid2game.put(gameid, curgame);
		}
		curgame.rgpeople.add(username);
		if (curgame.rgpeople.size()==cpeople.intValue())
			curgame.currentPlayer = new Integer (1);
		return new Integer(curgame.rgpeople.size());
	}
	
	public Integer wtLeaveGame(Integer gameid, String username)
	{
		WTGame curgame = m_wtid2game.get(gameid);
		if (curgame!=null)
			m_wtid2game.remove(gameid);
		return new Integer(0);
	}
	
	/**
	 * the user sends a new word for the sentence
	 * @return number of results
	 */
	public Integer wtSendNewWord(Integer gameid, String newWord)
	{
		WTGame curgame = m_wtid2game.get(gameid);
		if (curgame==null) {//game ended
			return new Integer(-1);
		}
		else if (curgame.sentence.length()!=0) {
			curgame.spacesentence.append(" ");
			curgame.sentence.append("%22");
		}
		curgame.sentence.append(newWord);
		String query = curgame.sentence.toString();
		curgame.cresult = new Integer(getNumSearchResults(query));
		int currentPlayer = curgame.currentPlayer.intValue();
		if (currentPlayer+1 == curgame.cpeople.intValue())
			 curgame.currentPlayer = new Integer(1);
		else
			curgame.currentPlayer = new Integer(currentPlayer+1);
		return curgame.cresult;
	}
	
	public paleGoldenRod.client.WTGameStatus wtGetStatus(Integer gameid)
	{
		WTGame curgame = m_wtid2game.get(gameid);
			
		paleGoldenRod.client.WTGameStatus curstatus = new paleGoldenRod.client.WTGameStatus();
		curstatus.currentCount = curgame.cresult;
		curstatus.currentPlayer = curgame.currentPlayer;
		curstatus.currentString = curgame.spacesentence.toString();
		
		return curstatus;
	}
	
	// public void wtLeaveGame(int gameid);
	
	/**
	 * this function returns number of result given HTTP page from google
	 * @param webpage the http page
	 * @return number of results 
	 */
//	private static int getNumResult(String webpage)
//	{
//		// the result number is right after "of about <b>" and before "</b>"
//		final String PRETEXT = "of about <b>";
//		final int ixBegin = webpage.indexOf(PRETEXT) + PRETEXT.length();
//		final String POSTTEXT = "</b>";
//		final int ixEnd = webpage.indexOf(POSTTEXT, ixBegin);
//		// now the result is at [ixBegin, ixEnd)
//		return Integer.valueOf(webpage.substring(ixBegin, ixEnd)).intValue();
//	}
	
	/*
	 * =========== Above functions are for Word train ==============
	 */
	
	public int getNumSearchResults(String text) {
	    String URL = "";
	    try {
	        Socket s = new Socket("www.google.com",80);
	        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
	        bw.write("GET /search?hl=en&q=" + URLEncoder.encode(text) + " HTTP/1.0\r\n");
	        bw.write("User-Agent: Mozilla/1.0 (compatible; NCSA Mosaic; Atari 800-ST)\r\n");
	        bw.write("Connection: close\r\n\r\n");
	        bw.flush();
	        
	        InputStreamReader in = new InputStreamReader(s.getInputStream());
	        BufferedReader buffer = new BufferedReader(in);
	        String line;
	        int i;
	        System.out.println("got here");
	        while((line = buffer.readLine()) !=null){
	        	//System.out.println(line);
	        	if((i = line.indexOf("</b> of about <b>"))>=0){
	        		String results = line.substring(i+17);
	        		int end = results.indexOf("</b>");
	        		results = results.substring(0, end).replace(",", "");
	        		System.out.println("Pattern Found:" + results);
	        		URL= results;
	        		break;
	        	}
	        }
	        in.close();
	    } catch (Exception e) {}
	    return Integer.parseInt(URL);
	}
}